home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 17.1 KB | 523 lines | [TEXT/MPS ] |
- // UStream.h
- // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
- // Originally written by Larry S. Rosenstein. Used by permission
-
-
- #ifndef __USTREAM__
- #define __USTREAM__
-
- // MacApp
-
- #ifndef __GEOMETRY__
- #include "Geometry.h"
- #endif
-
- #ifndef __TOOLBOX__
- #include "Toolbox.h"
- #endif
-
- #ifndef __UGEOMETRY__
- #include "UGeometry.h"
- #endif
-
- #ifndef __UOBJECT__
- #include "UObject.h"
- #endif
-
- // Toolbox
-
-
- //----------------------------------------------------------------------------------------
- // Forward class declarations.
- //----------------------------------------------------------------------------------------
-
- // class TFile;
- class TList;
-
- //----------------------------------------------------------------------------------------
- // This unit implements a rudimentary stream abstract type, and subclasses that do I/ O
- // to files and handles. This can be used to implement document I/ O and clipboard I/ O
- // with the same code. Streams can write out and read back objects, using the features
- // in UObject to get an object's class ID and name. The format of an object in the stream
- // is as follows:
- //
- // 2 bytes delimiter
- // if (delimiter == kNullObject) no object, so...
- // that's all folks!
- // else if (delimiter == kIndex) object has been seen
- // 4 bytes index into TContext
- // else
- // {
- // if (delimiter == kClassID)
- // 4 bytes class ID (at the time it was written) 4 bytes for model far code
- // else if (delimiter == kSignature)
- // 4 bytes signature
- // 4 bytes size of object in stream, excluding class ID
- // 1 byte size of class name
- // n bytes class name
- // m bytes data specific to object
- // }
- //
- // The class ID in the stream might not match the class ID of the same class in the
- // current application. (It depends on how the class IDs were assigned.) The stream code
- // uses the class name to identify the actual class. It is not necessary, however, to
- // write out the class name for every class. The stream will associate the classID in
- // the stream with the correct class ID for the application. The first object of a given
- // class has its name written into the stream, along with its classID. When read back,
- // the name is used to find the class ID in the current application, which is associated
- // with the class ID in the stream. Subsequent objects of that class can be written with
- // an empty class name, and the table of class IDs will be consulted to find out the
- // proper class ID.
- //
- // TStream handles structures in which objects are referenced more than once using
- // TContext which maintains a table of all the objects written out. The first time an
- // object is written it is added to the table.If the same object is written again, only
- // its table index is written. A similar process is used to read the object back.
- //
- // TStream will skip over objects that it can't understand.To do this, it writes the size
- // of each object in a known position.This means that writing an object is a 2 step
- // process. You first write the object header, by calling WriteObject, and after the entire
- // object is written you fill in its size, by calling WriteObjectSize.
- //
- // TStream::ReadObject will return NULL if it can't understand a particular object, or if
- // the object was actually NULL. It returns a flag indicating the difference.
- //----------------------------------------------------------------------------------------
-
- // passed to WriteStreamObject
- enum
- {
- kNoStandardObject, kStandardObject
- };
-
- // written by WriteStreamObject, read by ReadStreamObject
- enum
- {
- kNullObject, kLocalObjectNumber, kClassIDAndClassname, kSignatureAndClassname
- };
-
- // passed to TContext::Add()
- enum
- {
- kDontForceReplacement, kForceReplacement
- };
-
- //----------------------------------------------------------------------------------------
- // TContext: This is the context which holds references to objects "seen" by the stream.
- //----------------------------------------------------------------------------------------
- typedef long LocalObjectNumber;
-
- class TContext : public TObject
- {
- MA_DECLARE_CLASS;
-
- public:
- //------------------------------------------------------------------------------------
- // Creation/Destruction
- //------------------------------------------------------------------------------------
-
- TContext();
- // Constructor
-
- void IContext();
-
- virtual ~TContext();
- // Called to dispose of an object. Gives object a chance to clean up after itself.
- // Default simply calls this->ShallowFree, which makes no attempt to free instance
- // variables. Should be overridden by any class which allocates space or owns
- // other objects in its instance variables. Be sure to call Inherited!
-
- //------------------------------------------------------------------------------------
- // Miscellaneous protocol and support methods.
- //------------------------------------------------------------------------------------
-
- virtual TObject* Clone();
- // Makes a duplicate copy of this. The default calls this->ShallowClone, which
- // makes a literal copy of instance variables but does not attempt to clone owned
- // objects. A subclass which owns other objects should override this to clone the
- // owned objects and data structures as well.
-
- //------------------------------------------------------------------------------------
- // Context Methods
- //------------------------------------------------------------------------------------
-
- virtual LocalObjectNumber Add(TObject* objectToAdd,
- Boolean forceReplacement,
- Boolean& newEntry);
-
- virtual TObject* Find(LocalObjectNumber name);
-
- //------------------------------------------------------------------------------------
- // data members
- //------------------------------------------------------------------------------------
- public:
-
- TList* fOtherObjects; // the objects "seen" by this context
-
- };
-
-
- typedef struct ClassIDEntry
- {
- long fOldID;
- long fNewID;
- } *PClassIDEntry, **HClassArray;
-
-
- //----------------------------------------------------------------------------------------
- // TStream: This is the abstract stream class. You would normally create instances of one
- // of the concrete subclasses below.
- //----------------------------------------------------------------------------------------
-
- class TStream : public TObject
- {
- MA_DECLARE_CLASS;
-
- public:
- //------------------------------------------------------------------------------------
- // Creation/Destruction
- //------------------------------------------------------------------------------------
-
- TStream();
- // Constructor
-
- void IStream();
-
- virtual ~TStream();
-
- //------------------------------------------------------------------------------------
- // Access: These methods have default implementations that assume a 0-length stream.
- //------------------------------------------------------------------------------------
-
- virtual long GetPosition();
-
- virtual void SetPosition(long newPosition);
-
- virtual long GetSize();
-
- virtual void SetSize(long newSize);
-
-
- //------------------------------------------------------------------------------------
- // TContext mgmt.
- //------------------------------------------------------------------------------------
-
- inline void SetContext(TContext* itsContext)
- { fContext = itsContext; }
-
- inline TContext* GetContext()
- { return fContext; }
-
- //------------------------------------------------------------------------------------
- // Note - all reading and writing methods signal failure in case of an I/ O error.
- //------------------------------------------------------------------------------------
-
- Boolean AtEnd();
- // Return true if at the end of the stream.
-
- virtual void ReadBytes(void* p, long count);
- // This must be overridden by subclasses; all other reading methods call this.
-
- Byte ReadByte();
-
- Boolean ReadBoolean();
-
- void ReadCharacter(short& data);
-
- short ReadInteger();
-
- long ReadLong();
-
- CPoint ReadPoint();
-
- void ReadVPoint(VPoint& data);
-
- void ReadRect(CRect& data);
-
- void ReadVRect(VRect& data);
-
- void ReadRGBColor(CRGBColor& data);
-
- IDType ReadIDType();
-
- void ReadString(CString& data, short maxSize);
- // Read a CString.maxSize is the amount of memory available, which is the maximum
- // CString length + 1.If the size of the CString in the stream is too large, then
- // it signals Failure with err=paramErr.
-
- Handle ReadHandle();
- // Read a handle from the stream and return it.
-
- Boolean ReadObject(TObject*& data);
- // Returns an uninitialized object; known is set to true if the object was valid
- // (i.e., the class of the object is known to the program. The function result
- // will be NULL if the object was unknown or if NULL was found in the stream.
-
- Boolean ReadStdObject(TObject*& data);
-
- Boolean ReadStreamObject(TObject*& data);
- // If stdObject is true, calls ReadStdObject, else calls ReadObject. If the
- // result is not NULL, calls ReadFrom on the new object.
-
- void ReadWordAlign();
- // calls ReadBytes to bump ptr 1 byte to word align
-
-
- //------------------------------------------------------------------------------------
- // Writing
- //------------------------------------------------------------------------------------
-
- virtual void WriteBytes(const void* p,
- long count);
- // This must be overridden by subclasses; all other writing methods call this.
-
- void WriteByte(Byte data);
-
- void WriteBoolean(Boolean data);
-
- void WriteCharacter(short data);
-
- void WriteInteger(short data);
-
- void WriteLong(long data);
-
- void WritePoint(CPoint data);
-
- void WriteVPoint(const VPoint& data);
-
- void WriteRect(const CRect& data);
-
- void WriteVRect(const VRect& data);
-
- void WriteRGBColor(const CRGBColor& data);
-
- void WriteIDType(const IDType data);
-
- void WriteString(const CString& data);
- // Write a CString. This takes a CStringPtr, so it can accommodate any size CString.
-
- void WriteHandle(const Handle aHandle);
- // Locks the handle, dereferences it, and calls WriteBytes for the size of the
- // handle. Restores the handle to the state it was in.
-
- //------------------------------------------------------------------------------------
- // These methods are used to write an object to a stream.You must call WriteObject
- // first, then tell the object to write its specific data, and then call
- // WriteObjectSize.
- //------------------------------------------------------------------------------------
-
- void WriteObject(TObject* data, long& sizePosition);
-
- void WriteStdObject(TObject* data,
- long& sizePosition);
-
- void WriteObjectSize(long sizePosition);
-
- void WriteStreamObject(TObject* data,
- Boolean stdObject = kNoStandardObject);
- // This calls WriteObject, then data->WriteTo, and finally WriteObjectSize.
-
- void WriteWordAlign();
- // calls WriteBytes to bump ptr 1 byte to word align
-
-
- //------------------------------------------------------------------------------------
- // Class handling: used internally
- //------------------------------------------------------------------------------------
-
- long LookupClassID(long id);
-
- void RegisterClassID(long oldID, long newID);
-
- //------------------------------------------------------------------------------------
- // data members
- //------------------------------------------------------------------------------------
- public:
-
- TContext* fContext; // remembers "seen" objects
-
- HClassArray fClassMap; // handle to class ID mapping table
-
- short fClassMapSize; // number of entries in the table
- };
-
-
- //----------------------------------------------------------------------------------------
- // THandleStream: This implements a stream into or out of a handle.The client is
- // responsible for allocating and disposing the handle.
- //----------------------------------------------------------------------------------------
-
- class THandleStream : public TStream
- {
- MA_DECLARE_CLASS;
-
- public:
- //------------------------------------------------------------------------------------
- // Creation/Destruction
- //------------------------------------------------------------------------------------
-
- THandleStream();
- // Constructor
-
- void IHandleStream(Handle itsHandle, long growth);
- // Initialize stream; growth specifies how much to grow the handle when it needs
- // to grow. You use this so that the handle isn't grown by a small number of bytes
- // on each write operation.
-
- virtual ~THandleStream();
- // This also shrinks the handle to the current position, eliminating any extra
- // space at the end.
-
-
- //------------------------------------------------------------------------------------
- // Subclass implementations
- //------------------------------------------------------------------------------------
-
- virtual long GetPosition();
-
- virtual void SetPosition(long newPosition);
-
- virtual long GetSize();
-
- virtual void SetSize(long newSize);
-
- virtual void ReadBytes(void* p, long count);
-
- virtual void WriteBytes(const void* p, long count);
-
-
- //------------------------------------------------------------------------------------
- // Growing
- //------------------------------------------------------------------------------------
-
- virtual long GrowthSize(long needed);
- // Returns amount to grow by, given that we need 'needed' bytes.Default is to grow
- // by Max(fGrowth, needed).
-
- //------------------------------------------------------------------------------------
- // data members
- //------------------------------------------------------------------------------------
- public:
-
- Handle fHandle; // the actual handle
-
- long fPosition; // offset into the handle
-
- long fSize; // size of the stream (may be smaller than
- // handle)
-
- long fGrowthSize; // how much to grow the handle when needed
- //
-
- char fSavedState; // handle's saved state
-
- };
-
-
- //----------------------------------------------------------------------------------------
- // TCountingStream: This implements a stream that counts up the total number of bytes. It
- // is only usable for writing. You will get a debugging break if you try to read from this
- // kind of stream.
- //----------------------------------------------------------------------------------------
-
- class TCountingStream : public TStream
- {
- MA_DECLARE_CLASS;
-
- public:
- //------------------------------------------------------------------------------------
- // Creation/Destruction
- //------------------------------------------------------------------------------------
-
- TCountingStream();
- // Constructor
- virtual ~TCountingStream();
- // Destructor
-
- inline void ICountingStream()
- { IStream(); }
-
-
-
- //------------------------------------------------------------------------------------
- // Subclass implementations
- //------------------------------------------------------------------------------------
-
- virtual long GetPosition(); // Override
- virtual void SetPosition(long newPosition); // Override
- virtual long GetSize(); // Override
- virtual void SetSize(long newSize); // Override
-
- virtual void WriteBytes(const void* p, long count); // Override
-
- //------------------------------------------------------------------------------------
- // data members
- //------------------------------------------------------------------------------------
- public:
-
- long fPosition; // current position in the stream
-
- long fSize; // current size of stream
-
- };
-
-
- //----------------------------------------------------------------------------------------
- // TResourceStream: This implements a stream that reads and writes to partial resources.
- // Since the partial resources traps are only available in System 7, this stream class can
- // only be used under System 7.
- //----------------------------------------------------------------------------------------
-
- class TResourceStream : public TStream
- {
- MA_DECLARE_CLASS;
-
- public:
- //------------------------------------------------------------------------------------
- // Creation/Destruction
- //------------------------------------------------------------------------------------
-
- TResourceStream();
- // Constructor
- virtual ~TResourceStream();
- // Destructor
-
- void IResourceStream(ResType theType, ResNumber theID);
- // Initialize the TResourceStream.
-
- //------------------------------------------------------------------------------------
- // Subclass implementations
- //------------------------------------------------------------------------------------
-
- virtual long GetPosition();
- // Returns fPosition.
-
- virtual void SetPosition(long newPosition);
- // Sets fPosition.
-
- virtual long GetSize();
- // Returns fSize.
-
- virtual void SetSize(long newSize);
- // Sets fSize.
-
- virtual void ReadBytes(void* p, long count);
- // Reads bytes from the resource calling ReadPartialResource.
-
- virtual void WriteBytes(const void* p, long count);
- // Write bytes to the resource calling WritePartialResource.
-
- //------------------------------------------------------------------------------------
- // data members
- //------------------------------------------------------------------------------------
- public:
-
- Handle fResource; // the resource to write to/ read from
-
- long fPosition; // offset into the resource
-
- long fSize; // offset into the resource
- };
-
-
- #endif // __USTREAM__
-